// TODO: 2025/5/18  
import java.util.ArrayList;
import java.util.Arrays;

public class TestDemo2 {
    /*//第二个构造：
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//这个数组就等于那个默认容量置空数组
    }*/

        //list.add(10);
        //list.add(11);
        //list.add(12);
        //list.add(1,999999999);
        //System.out.println(list);
        //但是我们通过add等这些的一系列的方法添加的数据那么会存放在哪里呢？


    public static void main(String[] args) {
        ArrayList<Integer> test = new ArrayList<>();
        test.add(1);//这种add方法就是默认添加后末尾
        test.add(2);
        test.add(3);
        System.out.println(test);
        //源码的学习：
        /*
        无参构造方法：
        public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//默认置空数组
        }

        //封装方法：
        add方法：
        public boolean add(E e) {
            modCount++;
            add(e, elementData, size);
            return true;
        }

        add中的添加末尾方法：
        private void add(E e, Object[] elementData, int s) {
            if (s == elementData.length)//第一种触发扩容方法：这个时候s为默认值为0，并且这个时候数组也是为默认置空数组所以长度为0
                elementData = grow();//所以进入到了grow方法中去进行扩容
            elementData[s] = e;
            size = s + 1;
        }

        //第二种触发扩容方法：就是当数组放满了，那么size就是为数组的长度，那么也会是触发这个扩容方法


        扩容方法：
        //java17进行封装了，封装方法
        private Object[] grow() {
            return grow(size + 1);//进入到这个时候就是size为0的时候
        }


        //原本的Java的方法：
        private Object[] grow(int minCapacity) {//所以这个时候就是minCapacity的参数size+1,那么这个值为1
            int oldCapacity = elementData.length;//这个时候还是默认置空数组，那么它的值就是0，
            if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

            //oldCapacity这个数据的值为0，也不是小于0，并且这个数组的长度还是默认置空数组的长度，所以不满足这个条件，
            //那么直接走else


                int newCapacity = ArraysSupport.newLength(oldCapacity,
                              minCapacity - oldCapacity, // minimum growth //
                              oldCapacity >> 1           // preferred growth //);
                return elementData = Arrays.copyOf(elementData, newCapacity);
            } else {
                return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];

                //那么这个时候就是在默认数据的值为10和size+1之间去取最大的
            }
        }




        //如果是第二种触发机制，那么这个时候的oldCapacity的就是大于0，并且数组或许是等于10（因为是第一次扩容之后放满了）或许是不等于10,那就不是至少前两次的扩容
        //那么直接走if下的部分，就是1.5倍的扩容了

        int newCapacity = ArraysSupport.newLength(oldCapacity,
                              minCapacity - oldCapacity,
                              oldCapacity >> 1)
        oldCapacity就是10，minCapacity是数组的size+1,那么就是11,因为放满了嘛，所以就是加1
        那么这个差值就是1
        而oldCapacity就是位运算，向右移动
        那么我们可以看一下：
        newLength的方法：


        public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // preconditions not checked because of inlining
        // assert oldLength >= 0
        // assert minGrowth > 0

        int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
        if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
            return prefLength;
        } else {
            // put code cold in a separate method
            return hugeLength(oldLength, minGrowth);
        }
    }

    //oldLength = 10, minGrowth = 1, preGrowth = 5
    //那么我可以细看：
    prefLength是10 + 5
    //public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;//这个是这个数组的扩容的长度最大值，即是Integer-8
    15小于最大值并且是大于0，所以直接返回这个15
    //如果大于最大值，那么走else直接返回Integer的最大值,不减去8

        */


        //test.add(1);
        //我们就拿add(1)举例子，往里传入了参数为1
        //这个时候e就是1，s代表顺序表中的实际的逻辑长度，但是也是为0
        //那么这个时候就要走到了扩容方法grow，
        //这个时候就要看具体实现



        //那么这个时候的结论就是：
        //就是在第一次add的时候分配内存，大小就是10
        //如果后面满了，那么就是1.5倍进行扩容
    }
}
